home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
portfoli
/
bootst11.lzh
/
PF BOOTSTRAP VATIPX PSLIPC
< prev
next >
Wrap
Text File
|
1991-05-02
|
5KB
|
234 lines
#ifndef lint
static char *sccsid = "%W% MS/ACF %E%";
#endif
/*
* tip/slip.c
*
* This file contains the SLIP specific startup code. It is designed
* with both BSD sockets and Sun Streams in mind, though the socket
* version has not been tested lately (but it SHOULD work). The Streams
* code is for SunOS 4.0[.1].
*
* The code to set the route (basically an internal shell script) may
* need tweeking on other systems, though it works on any of the
* systems I have run into.
*
* The alarm/DCD code is a HACK to detect loss of the line in the
* absense of proper modems status signaling (broken in SunOS when
* using the dialout device, serial line minor devices 128-255).
* This has been reported, but I suspect that a fix will have to
* wait for SunOS 4.2 or maybe 4.1.?.
*
* Doug Kingston <dpk@morgan.com>
* 880219
*/
#include "tip.h"
#include <sys/socket.h>
#ifdef STREAMS
#include <sys/stropts.h>
#include <sys/sockio.h>
#include <sys/termios.h> /* has defines that clash with ioctl.h */
/* #include <sys/slip.h> */
#include "slip.h"
#endif STREAMS
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#define DCD_SETTLING_TIME 1 /* time between DCD change and status check */
#define DCD_CHECK_INTERVAL 15 /* if > 0, time between automatic DCD checks */
int gotsig = 0;
sigfunc_t dcd_handler();
runslip()
{
int unit, s;
struct ifreq ifr;
#ifdef I_POP /* Using streams */
struct termios tios;
/* pop all streams modules */
while (ioctl(FD, I_POP, 0) == 0)
continue;
/* set up the line parameters */
if (ioctl(FD, TCGETS, (caddr_t)&tios) < 0) {
perror("ioctl (TCGETS)");
return(1);
}
tios.c_cflag = (tios.c_cflag&(CBAUD|CIBAUD))|CS8|CREAD|HUPCL;
tios.c_iflag = IGNBRK;
if (ioctl(FD, TCSETS, (caddr_t)&tios) < 0) {
perror("ioctl (TCSETS)");
return(1);
}
/* push the SLIP module */
if (ioctl(FD, I_PUSH, "slip") < 0) {
perror("ioctl (I_PUSH)");
return(1);
}
/* find out what unit number we were assigned */
if (ioctl(FD, SLIOGUNIT, (caddr_t)&unit) < 0) {
perror("ioctl (SLIOGUNIT)");
return(1);
}
#else /* not streams */
int ldisc = SLIPDISC;
if (ioctl(FD, TIOCSETD, &ldisc) < 0) {
perror("slipd: TIOCSETD");
return(1);
}
if (ioctl(FD, TIOCGETD, &unit) < 0) { /* Hack to get slip number */
perror("slipd: TIOCGETD");
return(1);
}
#endif I_POP
/* set the local and remote interface addresses */
s = socket(AF_INET, SOCK_DGRAM, 0);
(void) sprintf(ifr.ifr_name, "slip%d", unit);
if (in_getaddr(DA, &ifr.ifr_addr) != 0 ||
ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
perror("ioctl (SIOCSIFDSTADDR)");
return(1);
}
/* this has the side-effect of marking the interface up */
if (in_getaddr(SA, &ifr.ifr_addr) != 0 ||
ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
perror("ioctl (SIOCSIFADDR)");
return(1);
}
if (in_getaddr(SM, &ifr.ifr_addr) != 0) {
if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
perror("ioctl (SIOCSIFADDR)");
return(1);
}
}
/* Set up default route if desired and not already present */
if (boolean(value(SETROUTE))) {
char buf[256];
char *argv[4];
char *envp[2];
int status;
sprintf(buf, "if eval 'netstat -r|grep -s \"^default\"';\
then echo default route already installed;\
else route add 0 %s 3; fi", SA);
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = buf;
argv[3] = (char *)0;
envp[0] = "PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/etc";
envp[1] = (char *)0;
switch (fork()) {
case 0: /* Child */
execve(argv[0], argv, envp);
exit(1);
case -1:
perror("tip: route add: fork");
break;
default: /* Parent */
wait(&status);
}
}
fprintf(stderr, "\07[SLIP running]\r\n");
/* set up signal handlers */
(void) sigblock(sigmask(SIGALRM));
(void) signal(SIGALRM, dcd_handler);
#if defined(SIGDCD) && SIGDCD > 0
(void) signal(SIGDCD, dcd_handler);
#endif
/* twiddle thumbs until we get a signal */
while (1) {
alarm(DCD_CHECK_INTERVAL);
sigpause(0);
#if defined(SIGDCD) && SIGDCD > 0
(void) sigblock(sigmask(SIGALRM)|sigmask(SIGDCD));
#else
(void) sigblock(sigmask(SIGALRM));
#endif SIGDCD
if (gotsig && lowdcd(FD)) {
sleep(DCD_SETTLING_TIME);
if (lowdcd(FD))
break;
}
gotsig = 0;
}
return(0);
}
abort_slip()
{
#ifdef STREAMS
/* pop the SLIP stream module */
while(ioctl(FD, I_POP, 0) == 0);
#else
int ldisc = 0;
(void)ioctl(FD, TIOCSETD, &ldisc);
#endif
}
sigfunc_t
dcd_handler()
{
gotsig = 1;
}
/* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
int
lowdcd(fd)
int fd;
{
int mbits;
if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
return 1; /* port is dead, we die */
return !(mbits & TIOCM_CAR);
}
in_getaddr(s, saddr)
char *s;
struct sockaddr *saddr;
{
register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
struct hostent *hp;
struct netent *np;
int val;
sin->sin_family = AF_INET;
val = inet_addr(s);
if (val != -1) {
sin->sin_addr.s_addr = val;
return(0);
}
hp = gethostbyname(s);
if (hp) {
sin->sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
return(0);
}
np = getnetbyname(s);
if (np) {
sin->sin_family = np->n_addrtype;
sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
return(0);
}
fprintf(stderr, "tip: in_getaddr: can't parse/lookup '%s'\n", s);
return(1);
}